<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<title>组件基础</title>
		<script src="../static/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>

	<body>
		<div id="app">
			<!--组件是可复用的 Vue 实例，且带有一个名字：在这个例子中是 <button-counter>。
				我们可以在一个通过 new Vue 创建的 Vue 根实例中，把这个组件作为自定义元素来使用：
				因为组件是可复用的 Vue 实例，所以它们与 new Vue 接收相同的选项，例如 data、computed、
				watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。-->
			<button-counter></button-counter>
			<br />
			<!--组件的复用：
			你可以将组件进行任意次数的复用：
			注意当点击按钮时，每个组件都会各自独立维护它的 count。
			因为你每用一次组件，就会有一个它的新实例被创建。-->
			<button-counter></button-counter>
			<button-counter></button-counter>
			<!--data 必须是一个函数
			当我们定义这个 <button-counter> 组件时，你可能会发现它的 data选项必须是一个函数，
				因此每个实例可以维护一份被返回对象的独立的拷贝：-->

			<!--组件的组织：
			通常一个应用会以一棵嵌套的组件树的形式来组织：
			例如，你可能会有页头、侧边栏、内容区等组件，每个组件又包含了其它的像导航链接、博文之类的组件。
			为了能在模板中使用，这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型：全局注册和
			局部注册。至此，我们的组件都只是通过 Vue.component 全局注册的：-->
			<!--通过 Prop 向子组件传递数据-->
			<blog-post title="My journey with Vue"></blog-post>
			<blog-post title="Blogging with Vue"></blog-post>
			<blog-post title="Why Vue is so fun"></blog-post>
			<!--
            	作者：zzhrainbow@163.com
            	时间：2018-07-22
            	描述：在一个典型的应用中，你可能在 data 里有一个博文的数组：
            -->
			<blog-post v-for="post in posts" v-bind:title="post.title" v-bind:key="post.id"></blog-post>
			<!--通过事件向父级组件发送消息:
			在我们开发 <blog-post> 组件时，它的一些功能可能要求我们和父级
			组件进行沟通。例如我们可能会引入一个可访问性的功能来放大博文的字号，
			同时让页面的其它部分保持默认的字号。在其父组件中，我们可以通过添加一个 
			postFontSize 数据属性来支持这个功能：-->
			<div v-bind:style="{fontSize:postFontSize + 'em'}">
				<blog-post-elements v-for="post in postElements" v-bind:post="post" v-bind:key="post.id" v-on:changeBigText="changeFontSize($event)">
				</blog-post-elements>
			</div>
			<!--使用事件抛出一个值
			有的时候用一个事件来抛出一个特定的值是非常有用的。例如我们可能想让 <blog-post> 
				组件决定它的文本要放大多少。这时可以使用 $emit 的第二个参数来提供这个值：-->

			<!--通过插槽分发内容:
				和 HTML 元素一样，我们经常需要向一个组件传递内容，像这样：
				幸好，Vue 自定义的 <slot> 元素让这变得非常简单：-->
			<alert-box>
				Something bad happened.
			</alert-box>
			<!--动态组件:
			可以通过 Vue 的 <component> 元素加一个特殊的 is 特性来实现：-->

			<button v-for="tab in tabs" v-bind:key="tab" v-bind:class="['tab-button', { active: currentTab === tab }]" v-on:click="currentTab = tab">{{ tab }}</button>
			<component v-bind:is="currentTabComponent" class="tab"></component>

		</div>
		<script type="text/javascript">
			Vue.component("buttonCounter", {
				data() {
					return {
						count: 0,
					}
				},

				template: "<button v-on:click='count++'>you clicked me {{count}} times</button>"
			})

			Vue.component('blog-post', {
				props: ['title'],
				template: '<h3>{{ title }}</h3>'
			})

			Vue.component('blog-post-elements', {
				props: ['post'],
				template: '<div ><h3>{{ post.title }}</h3> <button v-on:click="enlargeText" > enlarge text </button> <div v-html="post.content" > </div></div>',
				methods: {
					enlargeText() {
						this.$emit("changebigtext", 0.3) //注意这里的传送事件与父组件里监听的事件名字的区别
					}
				},

			})

			Vue.component('alert-box', {
				template: "<div class='demo - alert - box '><strong>Error!</strong><slot></slot> </div>"

			})

			Vue.component('tab-home', {
				template: '<div>Home component</div>'
			})
			Vue.component('tab-posts', {
				template: '<div>Posts component</div>'
			})
			Vue.component('tab-archive', {
				template: '<div>Archive component</div>'
			})

			var vm = new Vue({
				el: "#app",
				data: {
					posts: [{
							id: 1,
							title: "first blog",
						},
						{
							id: 2,
							title: "second blog",
						},
						{
							id: 3,
							title: "third blog",
						},
					],
					postFontSize: 1,
					postElements: [{
							id: 2016,
							content: "<p>1.为了变大数据</p>",
						},
						{
							id: 2017,
							content: "<p>2.第二条</p>",
						},
						{
							id: 2018,
							content: "<p>3.第三条来了</p>",
						},

					],
					currentTab: 'Home',
					tabs: ['Home', 'Posts', 'Archive']
				},
				methods: {
					changeFontSize(changeValue) {
						this.postFontSize += changeValue
					}
				},
				computed: {
					currentTabComponent() {
						return "tab-" + this.currentTab.toLowerCase()
					}
				}
			})
		</script>

		<style type="text/css">
			.tab-button {
				padding: 6px 10px;
				border-top-left-radius: 3px;
				border-top-right-radius: 3px;
				border: 1px solid #ccc;
				cursor: pointer;
				background: #f0f0f0;
				margin-bottom: -1px;
				margin-right: -1px;
			}
			
			.tab-button:hover {
				background: lightgray;
			}
			
			.tab-button.active {
				background: lightgray;
			}
			
			.tab {
				border: 1px solid #ccc;
				padding: 10px;
				background: lightpink;
			}
		</style>

	</body>

</html>